package com.winsth.libs.utils;

import android.text.TextUtils;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 创建人：ZhaoGang
 * 创建时间：2021-06-09 16:00
 * 文件描述:
 */
public class ZipUtil {
    /**
     * 解压指定zip文件到指定目录
     *
     * @param zip  zip文件地址
     * @param dest 解压目录
     * @param pass 密码
     * @return
     * @throws ZipException
     */
    public File[] unzip(String zip, String dest, String pass) throws ZipException {
        File zipFile = new File(zip);
        return unZip(zipFile, dest, pass);
    }

    /**
     * 解压指定zip文件到指定目录
     *
     * @param zipFile zip文件
     * @param dest    解压目录
     * @param pass    密码
     * @return
     * @throws ZipException
     */
    @SuppressWarnings("unchecked")
    public File[] unZip(File zipFile, String dest, String pass) throws ZipException {
        ZipFile zFile = new ZipFile(zipFile);
        zFile.setFileNameCharset("UTF-8");
        if (!zFile.isValidZipFile()) {
            throw new ZipException("文件损坏或者非ZIP文件");
        }
        File destDir = new File(dest);
        if (destDir.isDirectory() && !destDir.exists()) {
            destDir.mkdir();
        }
        if (zFile.isEncrypted()) {// 设置密码
            zFile.setPassword(pass.toCharArray());
        }
        zFile.extractAll(dest);// 解压
        List<FileHeader> headerList = zFile.getFileHeaders();
        List extractedFileList = new ArrayList();
        for (FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir, fileHeader.getFileName()));
            }
        }
        File[] extractedFiles = new File[extractedFileList.size()];
        extractedFileList.toArray(extractedFiles);
        try {
            zipFile.delete();
        } catch (Exception e) {
            LogUtil.exportLog(CommonUtil.getCName(new Exception()), CommonUtil.getMName(new Exception()), "UnsupportedEncodingException:" + e.getMessage(),
                    true);

        }
        return extractedFiles;
    }

    /**
     * 压缩指定文件到指定目录下
     *
     * @param src  被压缩的源文件或者文件夹
     * @param dest 存放位置,需要具体到压缩后保存的名字,如   ------/xxx.zip
     * @param pass 解压密码
     */
    public void ZipAddPass(String src, String dest, String pass) {
        File srcFile = new File(src);
        dest = buildDestinationZipFilePath(srcFile, dest);
        ZipParameters zipp = new ZipParameters();
        zipp.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);//压缩方式
        zipp.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);//压缩级别
        if (!TextUtils.isEmpty(pass)) {//设置解压密码
            zipp.setEncryptFiles(true);
            zipp.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
            zipp.setPassword(pass);
        }
        try {
            ZipFile zipFile = new ZipFile(dest);
            zipFile.setFileNameCharset("UTF-8");
            if (srcFile.isDirectory()) {
                zipFile.addFolder(src, zipp);
            } else {
                zipFile.addFile(srcFile, zipp);
            }
        } catch (Exception e) {
            LogUtil.exportLog(CommonUtil.getCName(new Exception()), CommonUtil.getMName(new Exception()), "UnsupportedEncodingException:" + e.getMessage(),
                    true);
        }
    }

    /**
     * 创建压缩文件存放路径
     *
     * @param sourceFile 被压缩的文件
     * @param dest       目标路径
     * @return 压缩文件存放路径
     */
    private String buildDestinationZipFilePath(File sourceFile, String dest) {
        String result = "";
        if (TextUtils.isEmpty(dest)) {
            if (sourceFile.isDirectory()) {
                result = sourceFile.getParent() + File.separator + sourceFile.getName() + ".zip";
            } else {
                String fileName = sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."));
                result = sourceFile.getParent() + File.separator + fileName + ".zip";
            }
        } else {
            createIfNotExist(dest);
            File destFile = new File(dest);
            if (destFile.isDirectory()) {
                if (sourceFile.isDirectory()) {
                    if (dest.endsWith(File.separator)) {
                        result = dest + sourceFile.getName() + ".zip";
                    } else {
                        result = dest + File.separator + sourceFile.getName() + ".zip";
                    }
                } else {
                    if (dest.endsWith(File.separator)) {
                        result = dest + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")) + ".zip";
                    } else {
                        result = dest + File.separator + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")) + ".zip";
                    }
                }
            } else {
                result = dest;
            }
        }
        return result;
    }

    private void createIfNotExist(String dest) {
        File destFile = null;
        if (dest.endsWith(File.separator)) {
            destFile = new File(dest);
        } else {
            destFile = new File(dest.substring(0, dest.lastIndexOf(File.separator)));
        }
        if (!destFile.exists()) {
            destFile.mkdirs();
        }
    }
}
